#include "../headers/Main.h"

using namespace std;

// Writen by NeXoSE based on FLCode.c.
// @filename = full path of flsave profile.
// <-Return = string of decoded flsave file.
char* FeProfileDecodec(const char filename[]) {
    const char Gene[] = "Gene";
    const char PfRefer[]  = "FLS1";
    
    int InFileSize = 0;
    char *InFileStr = NULL, *OutputBuff = NULL, c = '\0', k = '\0', r = '\0';
    ifstream fin;
    bool IsLegal = true;
    
    fin.open(filename, ios::binary|ios::in);
    fin.seekg(0, ios::end);
    
	if (fin.tellg() < (int)strlen(PfRefer)) return "";
                     
    InFileSize = fin.tellg();
    InFileStr = new char [InFileSize + 1];
    
    fin.seekg(0, ios::beg);
    fin.read(InFileStr, InFileSize);
    
    fin.close();

    for (unsigned int i = 0; i < strlen(PfRefer); i++) {
       if ((int)InFileStr[i] != (int)PfRefer[i]) IsLegal = false;
    }
    
    if (IsLegal) {
		OutputBuff = InFileStr + strlen(PfRefer);
		//Core Arithmetic From FLCodec.c
        for (unsigned int i = (int)strlen(PfRefer), j = 0; i < strlen(OutputBuff) - strlen(PfRefer); i++, j++){
            c = OutputBuff[i];
            k = (Gene[i % 4] + i) % 256;
            
            r = c ^ (k | 0x80);
            
            OutputBuff[j] = r;
        }
        return OutputBuff;
    }
	delete[] InFileStr;
    return "";
}

// Writen by NeXoSE.
// @sPfile = content of decoded flsave file, saved as string.
// <-Return = URL styled string.
string FeProfileParse(string sPfile){
    string sData = "";
    istringstream pfstream;
    ostringstream dtstream;
    int iShipKilled = 0,
        iMissionCompleted = 0,
        iMissionFail = 0,
        iVisitedObject = 0,
        iVisitedSys = 0,
        iVisitedBase = 0,
        iVisitedHoles = 0,
        ivNPCs = 0,
        iRumors = 0;
        
	if (sPfile.length() > 0) {
		pfstream.str(sPfile);
		while(pfstream >> sPfile) {
			sPfile = Trim(sPfile);
			if (sPfile == "rank") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_rank=" << sPfile;
			} else if (sPfile == "rep_group") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_rep=" << ws2s(GetGroupName((unsigned int)CreateID(sPfile.c_str())));
			} else if (sPfile == "money") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_cash=" << sPfile;   
			} else if (sPfile == "system") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_sys=" << ws2s(GetSystemName((unsigned int)CreateID(sPfile.c_str())));     
			} else if (sPfile == "pos") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_pos=" << sPfile;      
			} else if (sPfile == "ship_archetype") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_ship=" << ws2s(GetShipName(atoi(sPfile.c_str())));     
			} else if (sPfile == "last_base") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_base=" << ws2s(GetBaseName((unsigned int)CreateID(sPfile.c_str())));     
			} else if (sPfile == "total_time_played") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; 
				dtstream << "&p_totaltime=" << sPfile;     
			} else if (sPfile == "ship_type_killed") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; pfstream >> sPfile;
				iShipKilled += atoi(sPfile.c_str()); 
			} else if (sPfile == "rm_completed") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; pfstream >> sPfile;
				iMissionCompleted += atoi(sPfile.c_str()); 
			} else if (sPfile == "rm_failed") {
				pfstream >> sPfile;
				if (sPfile == "=") pfstream >> sPfile; pfstream >> sPfile;
				iMissionFail += atoi(sPfile.c_str()); 
			} else if (sPfile == "visit") {
				iVisitedObject++; 
			} else if (sPfile == "vnpc") {
				ivNPCs++; 
			} else if (sPfile == "rumor") {
				iRumors++; 
			} else if (sPfile == "sys_visited") {
				iVisitedSys++; 
			} else if (sPfile == "base_visited") {
				iVisitedBase++; 
			} else if (sPfile == "holes_visited") {
				iVisitedHoles++; 
			} 
			pfstream.clear();
		}
		pfstream.str("");

		if (iShipKilled != 0) dtstream << "&p_shipkill=" << iShipKilled;
		if (iMissionCompleted != 0) dtstream << "&p_rm_comp=" << iMissionCompleted;
		if (iMissionFail != 0) dtstream << "&p_rm_fail=" << iMissionFail; 
		if (iVisitedObject != 0) dtstream << "&p_vobj=" << iVisitedObject;
		if (iVisitedBase != 0) dtstream << "&p_vbase=" << iVisitedBase; 
		if (iVisitedSys != 0) dtstream << "&p_vsys=" << iVisitedSys; 
		if (ivNPCs != 0) dtstream << "&p_rumors=" << ivNPCs;
		if (iRumors != 0) dtstream << "&p_vnpcs=" << iRumors; 

		sData = dtstream.str();

		dtstream.str("");  
	} else {
		return "";
	}

    return sData;
}

// Writen by NeXoSE.
// @wscCharname = char name, can be used when player online or offline.
// <-Return = full path of flsave file.
string FeProfilePfPath(wstring wscCharname) {
	wstring wscFeProfileDir = L"", wscFeProfileFile = L"";
	string scFeUserProfile = "";

	if (wscCharname == L"") return "";

	if(!HKHKSUCCESS(HkGetAccountDirName(wscCharname, wscFeProfileDir))){
		return "";
	}
	HkGetCharFileName(wscCharname, wscFeProfileFile);

	scFeUserProfile = scAcctPath + "\\" + wstos(wscFeProfileDir) + "\\" + wstos(wscFeProfileFile) + ".fl";

	if (file_exists(scFeUserProfile.c_str())) 
		return scFeUserProfile;
	else
		return "";
}